﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Windows.Threading;
using System.Collections.Specialized;
using DirectoryViewModels;
using System.Threading;
using BrainTechLLC.FileMaintenance;
using BrainTechLLC.WPF;
using DragDropLibrary;

using System.ComponentModel;
using BrainTechLLC.ThreadSafeObjects;
using System.Diagnostics;

namespace BrainTechLLC.FolderExplorer
{
    /// <summary>
    /// Interaction logic for FolderExplorerControl.xaml
    /// </summary>
    public partial class FolderExplorerControl : UserControl
    {
        public static Dispatcher _Dispatcher;
        public event EventHandler<ObjectEventArgs<FolderViewModel>> SelectFoldersStart;
        public event EventHandler<ObjectEventArgs<FolderViewModel>> SelectFoldersEnd;
        public FolderOperationHandler OperationHandler = new FolderOperationHandler();
        protected Point _lastPos = new Point(-1, -1);
        protected FolderViewModel _lastFolder;

        public FolderExplorerControl()
        {
            InitializeComponent();
            _Dispatcher = this.Dispatcher;
            OperationHandler.SelectFoldersStart += new EventHandler<ObjectEventArgs<FolderViewModel>>(OperationHandler_SelectFoldersStart);
            OperationHandler.SelectFoldersEnd += new EventHandler<ObjectEventArgs<FolderViewModel>>(OperationHandler_SelectFoldersEnd);
        }

        void OperationHandler_SelectFoldersEnd(object sender, ObjectEventArgs<FolderViewModel> e)
        {
            SelectFoldersEnd.RaiseEvent(this, e.obj);   
        }

        void OperationHandler_SelectFoldersStart(object sender, ObjectEventArgs<FolderViewModel> e)
        {            
            SelectFoldersStart.RaiseEvent(this, e.obj);
        }

        private void tvRoot_Loaded(object sender, RoutedEventArgs e)
        {
            TreeViewItem tvi = sender as TreeViewItem;
            //tvi.IsExpanded = true;
            StartTimers();
        }

        public int CountDirectoriesInMemory()
        {
            return RootFolder.GetAllFoldersInMemory().Count;
        }

        public int CountFilesInMemory()
        {
            return RootFolder.GetAllFilesInMemory().Count;
        }

        public FolderViewModel GetSelectedFolder()
        {
            if (treeView1.SelectedItem != null)
            {
                FolderViewModel folder = treeView1.SelectedItem as FolderViewModel;
                return folder;
            }

            return null;
        }

        private void gridMouseRightButtonDown_Click(object sender, MouseButtonEventArgs e)
        {
            Grid cm = sender as Grid;
            FolderViewModel f = cm.Tag as FolderViewModel;
            int idx = FindIndex(f);
            var tvi = _TreeViewItems[idx];
            if (!f.IsSelected || GetSelectedFolders().Count == 0)
            {
                ChangeSelectedState(tvi, !f.IsSelected, false);
            }
        }

        public void SizeBorder(Border b, List<Grid> grids)
        {
            double width = b.ActualWidth;
            if (width > 80)
            {
                for (int n = 0; n < grids.Count; n++)
                {
                    var tvi = grids[n];
                    FolderViewModel f = tvi.Tag as FolderViewModel;
                    var wid = width - 80 - ((f.Depth - 1) * 18);
                    if (wid > 0D)
                    {
                        tvi.Width = wid;
                    }
                }
            }
        }

        private void Border_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Border b = sender as Border;
            SizeBorder(b, AllGrids);
        }

        public void ShowAllDirSizes()
        {
            if (NoSizes)
            {
                return;
            }
            var folders = RootFolder.GetSubFoldersImmediate();
            _root.AddOperation("ShowDirSizes");

            ParameterizedThreadStart ts = new ParameterizedThreadStart(CalcDirSize);
            Thread t = new Thread(ts) { IsBackground = true, Priority = ThreadPriority.Lowest };
            t.Start(folders.ToList());
        }


        private void GetParents(FolderViewModel f, Dictionary<FolderViewModel, int> results)
        {
            if (!results.ContainsKey(f))
            {
                results.Add(f, 0);
            }

            if (f.Parent == null)
            {
                return;
            }

            if (f.Parent != null)
            {
                GetParents(f.Parent, results);
            }
        }

        private void colFolder_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //List<FolderViewModel> complete = new List<FolderViewModel>();
            //List<FolderViewModel> folders = RootFolder.FindFoldersWithoutCachedSubfolders(complete);
            //folders.Sort(new Comparison<FolderViewModel>((f1, f2) => f1.Depth.CompareTo(f2.Depth)));
            //var toProcess = folders.Take(10).ToList();
            //for (int n = 0; n < toProcess.Count; n++)
            //{
            //    FolderViewModel f = toProcess[n];
            //    f.PrefetchData(2D, 3D);
            //}
        }

        private void mnuDeleteAllSvn_Click(object sender, RoutedEventArgs e)
        {
            FolderViewModel f = (sender as MenuItem).Tag as FolderViewModel;

            var folders = GetSelectedFolders();
            FolderAndSelectionCriteria obj = new FolderAndSelectionCriteria() { AllFolders = folders, FolderSelected = f };
            ParameterizedThreadStart ts = new ParameterizedThreadStart(DeleteSvnWorker);
            Thread t = new Thread(ts) { IsBackground = true, Priority = ThreadPriority.BelowNormal };
            t.Start(obj);
        }

        private void DeleteSvnWorker(object o)
        {
            FolderAndSelectionCriteria obj = o as FolderAndSelectionCriteria;
            List<FolderViewModel> folders = obj.AllFolders;
            FolderViewModel f = obj.FolderSelected;
            bool found = false;
            List<FolderViewModel> deleted = new List<FolderViewModel>();

            for (int n = 0; n < folders.Count; n++)
            {
                FolderViewModel folder = folders[n];
                if (folder == f)
                {
                    found = true;
                }
                DeleteSvn(folder, deleted);
            }

            if (!found)
            {
                DeleteSvn(f, deleted);
            }

            deleted.RemoveDuplicates();
            deleted.ForEach(folder => Dispatcher.BeginInvoke(new VoidDelegate(() => folder.Parent.RefreshSubfolders())));
        }

        private void DeleteSvn(FolderViewModel vm, List<FolderViewModel> deleted)
        {
            var all = vm.GetSubFoldersImmediate();
            for (int n = 0; n < all.Count; n++)
            {
                var f = all[n];
                DirectoryInfo di = new DirectoryInfo(f.FullPath);
                if (di.Name.Equals(".svn"))
                {
                    try
                    {
                        FileWorker.SetFileAttribute(di, FileAttributes.Normal);
                        Directory.Delete(f.FullPath, true);
                        deleted.Add(f);
                    }
                    catch
                    {
                        // nothing
                    }
                }
                else
                {
                    DeleteSvn(f, deleted);
                }
            }
        }

        private void tvRoot_Expanded(object sender, RoutedEventArgs e)
        {
            FolderViewModel vm = (sender as Control).Tag as FolderViewModel;
            vm.CreateSubfolders();
        }

        //private void chk_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        //{
        //    FolderViewModel vm = (sender as CheckBox).Tag as FolderViewModel;
        //    SelectFoldersStart.RaiseEvent(this, vm);
        //}
    }
}
